package hn.sigit.model.hnd.ladmshadow.dao;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.ScrollableResults;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
import org.jboss.seam.Component;

import hn.sigit.model.hnd.ladmshadow.AdministrativeSource;
import hn.sigit.model.hnd.ladmshadow.Parcel;
import hn.sigit.model.hnd.ladmshadow.Party;
import hn.sigit.model.hnd.ladmshadow.Property;
import hn.sigit.model.hnd.ladmshadow.RRR;
import hn.sigit.model.hnd.ladmshadow.RequiredRelationshipBAUnit;
import hn.sigit.model.hnd.ladmshadow.SpatialSource;
import hn.sigit.model.hnd.ladmshadow.SpatialUnit;
import hn.sigit.model.util.SigitDAO;


public class PropertyDAO extends SigitDAO<Property> {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	private static String deletePropertiesHQL = "DELETE FROM Property WHERE presentationId = :presentationId";
	private static String deletePropertiesHQL2 = "DELETE FROM Property WHERE presentationId = :presentationId AND snapshot = :snapshot";

	
	protected PropertyDAO() {
	}
	
	public static Property loadPropertyById(long baUnitId) {
		return loadPropertyById(getSession(), baUnitId);
	}
	public static List<Property> loadPropertiesByPresentationId(long presentationId) {
		return loadPropertiesByPresentationId(getSession(), presentationId);
	}
	public static List<Property> loadRequestedPropertiesByPresentationId(long presentationId) {
		return loadRequestedPropertiesByPresentationId(getSession(), presentationId);
	}
	public static List<Property> loadNeighborPropertiesByPresentationId(long presentationId) {
		return loadNeighborPropertiesByPresentationId(getSession(), presentationId);
	}
	public static Property loadPropertyByPresentationIdAndLadmId(long presentationId, long ladmId) {
		return loadPropertyByPresentationIdAndLadmId(getSession(), presentationId, ladmId);
	}
	public static int deletePropertiesByPresentationId(long presentationId, boolean includeSnapshot) {
		return deletePropertiesByPresentationId(getSession(), presentationId, includeSnapshot);
	}
	public static int clearPropertiesAssociationsByPresentationId(long presentationId, boolean includeSnapshot) {
		return clearPropertiesAssociationsByPresentationId(getSession(), presentationId, includeSnapshot);
	}
	
	
	public static Property loadPropertyById(Session session, long baUnitId) {
		Criteria criteria = session.createCriteria(Property.class);
		criteria.add(Restrictions.eq("uID", baUnitId));

		return (Property) criteria.uniqueResult();
	}
	
	@SuppressWarnings("unchecked")
	public static List<Property> loadPropertiesByPresentationId(Session session, long presentationId) {
		Criteria criteria = session.createCriteria(Property.class);
		criteria.add(Restrictions.eq("presentationId", presentationId));

		return (List<Property>)criteria.list();
	}
	
	@SuppressWarnings("unchecked")
	public static List<Property> loadRequestedPropertiesByPresentationId(Session session, long presentationId) {
		Criteria criteria = session.createCriteria(Property.class);
		criteria.add(Restrictions.eq("presentationId", presentationId));
		criteria.add(Restrictions.eq("readOnly", false));
		
		return (List<Property>)criteria.list();
	}
	
	@SuppressWarnings("unchecked")
	public static List<Property> loadNeighborPropertiesByPresentationId(Session session, long presentationId) {
		Criteria criteria = session.createCriteria(Property.class);
		criteria.add(Restrictions.eq("presentationId", presentationId));
		criteria.add(Restrictions.eq("readOnly", true));
		
		return (List<Property>)criteria.list();
	}
	
	public static Property loadPropertyByPresentationIdAndLadmId(Session session, long presentationId, long ladmId) {
		Criteria criteria = session.createCriteria(Property.class);
		criteria.add(Restrictions.eq("presentationId", presentationId));
		criteria.add(Restrictions.eq("ladmId", ladmId));
		
		return (Property)criteria.uniqueResult();
	}

	public static int deletePropertiesByPresentationId(Session session, long presentationId, boolean includeSnapshot) {
		if (includeSnapshot) {
			return session.createQuery(deletePropertiesHQL)
				.setLong("presentationId", presentationId)
				.executeUpdate();
		}
		return session.createQuery(deletePropertiesHQL2)
			.setLong("presentationId", presentationId)
			.setBoolean("snapshot", includeSnapshot)
			.executeUpdate();
	}
	
	public static int clearPropertiesAssociationsByPresentationId(Session session, long presentationId, boolean includeSnapshot) {
		Criteria criteria = session.createCriteria(Property.class);
		criteria.add(Restrictions.eq("presentationId", presentationId));
		if (!includeSnapshot)
			criteria.add(Restrictions.eq("snapshot", false));
		
		ScrollableResults propertyCursor = criteria.scroll();
		
		Property property;
		int count = 0;
		while (propertyCursor.next()) {
			property = (Property) propertyCursor.get(0);
			
			property.setBaParty(null);
			property.setSpatialSources(null);
			property.setRrr(null);
			property.setBaunits1requiredrelationshipbaunits(null);
			property.setBaunits2requiredrelationshipbaunits(null);
			property.setSpatialUnits(null);
			property.setAdminSources(null);
			
			if (++count == 100) {
				session.flush();
				session.clear();
			}
		}
		
		propertyCursor.close();
		
		return count;
	}
}
